package com.intel.factorytest.ChamberMode;

import java.io.IOException;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.hardware.Camera.Parameters;
import android.hardware.Camera.PictureCallback;
import android.hardware.Camera.ShutterCallback;
import android.os.Bundle;
import android.view.Gravity;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.view.ViewGroup.LayoutParams;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.app.ActionBar;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.os.SystemProperties;
import android.os.CountDownTimer;
import android.os.Looper;
import android.app.StatusBarManager;
import android.view.KeyEvent;
import android.content.Context;

import com.intel.factorytest.R;
import com.intel.factorytest.util.LogUtils;
import com.intel.factorytest.util.Util;
import com.intel.factorytest.util.ShellUtilsPlus;
import com.intel.factorytest.ChamberMode.ChamberModeMainActivity;
import com.intel.factorytest.util.AutoFocusManager;



public class RearCameraTest extends Activity implements SurfaceHolder.Callback {

    private Button mStartButton;
    private Button mStopButton;
    private TextView mShowText;    
    Context mContext;
    private SurfaceView mCameraView = null;
    private android.hardware.Camera mCameraDevice = null;
    private Parameters parameters = null;
    SurfaceHolder holder;
    private int cameraId = 0;
    private String FlashMode;
    ActionBar  actionBar;
    private int mTimeout = 20000;
    private RearCameraDown mRearCameraDown = null;
    private LinearLayout mButtonView;    
    private boolean isShowButton = true;
    StatusBarManager mStatusBarManager;

    private AutoFocusManager autoFocusManager;
    //private static final int START_REAR_CAMERA_TEST_RESULT_CODE = 1;
    
    private static final int REAR_CAMERA_MSG_UPDATE_UI = 1;
    private static final int REAR_CAMERA_MSG_TEST_END = 2;

    private Handler mHandler = new Handler() {
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case REAR_CAMERA_MSG_TEST_END: {
                    removeMessages(REAR_CAMERA_MSG_TEST_END);                    
                    Util.isRearCameraTesting = false ;
                    SystemProperties.set("persist.sys.chamber_run","true");
                    finish();
                    break;
                }
                case REAR_CAMERA_MSG_UPDATE_UI: {
                     removeMessages(REAR_CAMERA_MSG_UPDATE_UI);
                     updateShowUI("");
                    break;
                }
                default:
                    break;
            }
        }
    };

    public void onCreate(Bundle b) {
        super.onCreate(b);
        LogUtils.logi("onCreate");
        mContext = getApplicationContext(); 
        getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
        Util.wakeUpAndKeepScreenOn(this);
        Util.setWindowBrightness(this,WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_FULL);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
                WindowManager.LayoutParams.FLAG_FULLSCREEN);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.chamber_mode_camera_test);
        mStatusBarManager = (StatusBarManager)getSystemService(STATUS_BAR_SERVICE);
        initView();
        mCameraView = (SurfaceView) findViewById(R.id.cameraView);

        if (2 == android.hardware.Camera.getNumberOfCameras()) {
            LogUtils.loge( "getNumberOfCameras.....2 ");
            try {
                mCameraDevice = android.hardware.Camera.open(0);// for the big
                parameters = mCameraDevice.getParameters();
                mCameraDevice.setParameters(parameters);
                cameraId = 0;
            } catch (Exception e) {
                LogUtils.loge( "openCamerawithholder 2 error ");
            }
        } else if (1 == android.hardware.Camera.getNumberOfCameras()) {
            LogUtils.loge( "getNumberOfCameras.....1 ");
            android.hardware.Camera.CameraInfo cameraInfo = new android.hardware.Camera.CameraInfo();
            android.hardware.Camera.getCameraInfo(0, cameraInfo);
            if (android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK == cameraInfo.facing) {
                try {
                    mCameraDevice = android.hardware.Camera.open(0);// for the
                    parameters = mCameraDevice.getParameters();
                    FlashMode=parameters.getFlashMode();
                    if (FlashMode!=null)
                    {
                        parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
                    }
                    mCameraDevice.setParameters(parameters);
                    cameraId = 0;
                } catch (Exception e) {
                    LogUtils.loge( "openCamerawithholder 1 error ");
                }
            } else {

            }
        } else {// not available camera

        }

        
        holder = mCameraView.getHolder();
        holder.addCallback(this);
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

    }

    protected void initView() {
        LogUtils.loge("initView");
        mShowText = (TextView) findViewById(R.id.showtext);
        mStartButton = (Button) findViewById(R.id.start);
        mStopButton = (Button) findViewById(R.id.stop);
        mStartButton.setEnabled(false);
        mStopButton.setEnabled(false);
        if(isShowButton) {
            mButtonView = (LinearLayout)findViewById(R.id.bottom);
            mButtonView.setVisibility(View.GONE);
        }

        mStartButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                v.setClickable(false);
                finish();
            }
        });

        mStopButton.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                // TODO Auto-generated method stub
                v.setClickable(false);
                finish();
            }
        });

    }

    public void onResume() {
        LogUtils.loge("onResume");
        super.onResume();
        SystemProperties.set("sys.cit.key.test","true");        
        SystemProperties.set("persist.sys.chamber_run","false");
        HideBottomMenu();
        mStartButton.setEnabled(true);
        mStopButton.setEnabled(true);
        Util.isRearCameraTesting = true;
        updateShowUI("Rear Camera");
        sendDelayedMsg(REAR_CAMERA_MSG_UPDATE_UI,5000,null,null);
        if (mTimeout > 0){
            LogUtils.logi("startRearCameraTest 20s");
            new countDownThread().start();
        }
        
        LogUtils.logi("onResume mCameraDevice = " + mCameraDevice);
        if (mCameraDevice == null)
        openCamerawithholder();
        LogUtils.loge("openCamerawithholder ok");
        try {
            mCameraDevice.startPreview();
            mCameraDevice.setDisplayOrientation(getDisplayOrientation(
                    getDisplayRotation(this), cameraId));
        } catch (NullPointerException e) {
            e.printStackTrace(System.err);
        }
    }
    /*
    public void setWindowBrightness(float brightness) {
        Window window = getWindow();
        WindowManager.LayoutParams lp = window.getAttributes();
        lp.screenBrightness = brightness;
        window.setAttributes(lp);
    }
    */
    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if ((keyCode == KeyEvent.KEYCODE_BACK) || (keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)){
           return true;
        }
        return super.onKeyDown(keyCode, event);
    }

    public void HideBottomMenu(){
        LogUtils.logi( "HideBottomMenu");
        mStatusBarManager.disable(StatusBarManager.DISABLE_MASK);
        actionBar = getActionBar();
        if(actionBar != null) {
               actionBar.hide();
        }
        View decorView = this.getWindow().getDecorView();        
        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_IMMERSIVE
                | View.SYSTEM_UI_FLAG_FULLSCREEN;
        decorView.setSystemUiVisibility(uiOptions);
        decorView.setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
                    @Override
                    public void onSystemUiVisibilityChange(int visibility) {
                        actionBar = getActionBar();
                        if(actionBar != null) {
                            actionBar.hide();
                        }
                        View decorView = getWindow().getDecorView();
                        int uiOptions = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
                                | View.SYSTEM_UI_FLAG_IMMERSIVE
                                | View.SYSTEM_UI_FLAG_FULLSCREEN;
                        decorView.setSystemUiVisibility(uiOptions);
                    }
            });
    }

    public void sendDelayedMsg(int msg, long delayMillis, String putString, String value){        
        LogUtils.logi( "sendDelayedMsg msg = " + msg + ",delaytime = " + delayMillis + ",putString = " + putString + ",value = " + value);
        if(!TextUtils.isEmpty(putString)&&!TextUtils.isEmpty(value)){
            Bundle b = new Bundle();
            b.putString(putString, value);
            Message m = Message.obtain(mHandler, msg);
            m.setData(b);
            mHandler.sendMessageDelayed(m, delayMillis);
        }else{
            Message m = Message.obtain(mHandler, msg);
            mHandler.sendMessageDelayed(m, delayMillis);
        }
    }
    public void updateShowUI(String text) {        
        LogUtils.logi( "updateShowUI text = " + text);
        mShowText.setText(text);
    }

    public int getDisplayRotation(Activity activity) {
        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        LogUtils.loge( "rotation:"+rotation);
        switch (rotation) {
        case Surface.ROTATION_0:
            return 0;
        case Surface.ROTATION_90:
            return 90;
        case Surface.ROTATION_180:
            return 180;
        case Surface.ROTATION_270:
            return 270;
        }
        return 0;
    }

    public int getDisplayOrientation(int degrees, int cameraId) {
        android.hardware.Camera.CameraInfo info = new android.hardware.Camera.CameraInfo();
        android.hardware.Camera.getCameraInfo(cameraId, info);
        int result;
        if (info.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT) {
            result = (info.orientation + degrees) % 360;
            result = (360 - result) % 360;
            LogUtils.loge( "info.orientation = " + info.orientation
                    + "  degrees = " + degrees + " result = " + result);
        } else {
            result = (info.orientation - degrees + 360) % 360;
            LogUtils.loge( "info.orientation = " + info.orientation
                    + "  degrees = " + degrees + " result = " + result);
        }
        return result;
    }

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        LogUtils.loge( "onConfigurationChanged() ");
        super.onConfigurationChanged(newConfig);
        if (mCameraDevice != null) {
            mCameraDevice.setDisplayOrientation(getDisplayOrientation(
                    getDisplayRotation(this), cameraId));
        }
    }

    private void openCamerawithholder() {
        //mCameraView.setVisibility(View.GONE);
        if (2 == android.hardware.Camera.getNumberOfCameras()) {
            LogUtils.loge( "getNumberOfCameras.....2 ");
            try {
                mCameraDevice = android.hardware.Camera.open(0);// for the big
                parameters = mCameraDevice.getParameters();
                mCameraDevice.setParameters(parameters);
                cameraId = 0;
            } catch (Exception e) {
                LogUtils.loge( "openCamerawithholder 2 error ");
            }
        } else if (1 == android.hardware.Camera.getNumberOfCameras()) {
            LogUtils.loge( "getNumberOfCameras.....1 ");
            android.hardware.Camera.CameraInfo cameraInfo = new android.hardware.Camera.CameraInfo();
            android.hardware.Camera.getCameraInfo(0, cameraInfo);
            if (android.hardware.Camera.CameraInfo.CAMERA_FACING_BACK == cameraInfo.facing) {
                try {
                    mCameraDevice = android.hardware.Camera.open(0);// for the
                    parameters = mCameraDevice.getParameters();
                    FlashMode=parameters.getFlashMode();
                    if (FlashMode!=null)
                    {
                        parameters.setFlashMode(Parameters.FLASH_MODE_TORCH);
                    }
                    mCameraDevice.setParameters(parameters);
                    cameraId = 0;
                } catch (Exception e) {
                    LogUtils.loge( "openCamerawithholder 1 error ");
                }
            } else {

            }
        } else {// not available camera

        }

        if (autoFocusManager == null && mCameraDevice != null) {
            autoFocusManager = new AutoFocusManager(mCameraDevice);
            autoFocusManager.setAutofocusInterval(2000);
            autoFocusManager.start();
        }

        try {
            if (mCameraDevice!= null)
            {
                LogUtils.loge( "mCameraDevice.startPreview()");
                mCameraDevice.setPreviewDisplay(holder);
                mCameraView.setVisibility(View.VISIBLE);
                //mCameraDevice.startPreview();
                //mCameraDevice.setDisplayOrientation(getDisplayOrientation(
                        //getDisplayRotation(this), cameraId));
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            LogUtils.loge( "startPreview error=====");
            e.printStackTrace();
        }

    }

    public void onPause() {
        super.onPause();        
        LogUtils.loge( "onPause() ");
        SystemProperties.set("sys.cit.key.test","false");
        if ( mRearCameraDown != null ) mRearCameraDown.cancel();
        
        if (autoFocusManager != null){
            autoFocusManager.stop();
            autoFocusManager = null;
        }

        if (mCameraDevice != null) {
            FlashMode=parameters.getFlashMode();
            if (FlashMode!=null)
            {
                parameters.setFlashMode(Parameters.FLASH_MODE_OFF);
            }
            mCameraDevice.setParameters(parameters);
            mCameraDevice.stopPreview();
            mCameraDevice.release();
            mCameraDevice = null;
        }
        //android.os.SystemProperties.set("service.camera.id", "0");
    }

    public void onDestroy() {
        LogUtils.loge( "onDestroy ");
        mStatusBarManager.disable(StatusBarManager.DISABLE_NONE);
        Util.setWindowBrightness(this,WindowManager.LayoutParams.BRIGHTNESS_OVERRIDE_NONE);
        if (mRearCameraDown != null) {
            mRearCameraDown = null;
        }        
        super.onDestroy();
    }

    /**
     * total 3 states, before preview, previewing, after capture ,
     */

    public void surfaceChanged(SurfaceHolder holder, int format, int width,
            int height) {
        LogUtils.loge( "surfaceChanged width=" + width + " height=" + height);

        try {
            if (mCameraDevice != null) {
                mCameraDevice.setPreviewDisplay(holder);
            }
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }

    public void surfaceCreated(SurfaceHolder holder) {
        // TODO Auto-generated method stub
        LogUtils.loge( "surfaceCreated ");
        // mCameraDevice = android.hardware.Camera.open(0);//for the big camera
    }

    public void surfaceDestroyed(SurfaceHolder holder) {
        LogUtils.loge( "surfaceDestroyed ");
        holder.removeCallback(this);  
    }

    @Override
    public void finish() {
        Intent i = new Intent();
        Bundle bundle = new Bundle();
        bundle.putString(ChamberModeMainActivity.REAR_CAMERA_RESULT, "rear_camera_test_finish");        
        i.putExtras(bundle);
        setResult(ChamberModeMainActivity.START_REAR_CAMERA_TEST_RESULT_CODE,i);        
        super.finish();
    }

    private class countDownThread extends Thread{
        public countDownThread(){}

        @Override
        public void run() {
            LogUtils.logi("countDownThread  run()");
            // TODO Auto-generated method stub
            Looper.prepare();
            mRearCameraDown = new RearCameraDown();
            mRearCameraDown.start();
            Looper.loop();
        }
    }
    
    private class RearCameraDown extends CountDownTimer{

        public RearCameraDown() {
            super(mTimeout,mTimeout);
        }

        @Override
        public void onFinish() {
            // TODO Auto-generated method stub
            LogUtils.logi("Time Out:");
            mHandler.sendEmptyMessage(REAR_CAMERA_MSG_TEST_END);
        }

        @Override
        public void onTick(long millisUntilFinished) {
            // TODO Auto-generated method stub
        }
    }
}
